#pragma once
#include<iostream>
#include<string>
#include<unistd.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>

//模拟进程间同步的过程

const std::string gpipeFile = "./fifo";
const mode_t gfifomode = 0600;
const int gdefultfd = -1;
const int gsize = 1024;
const int gFoeRead = O_RDONLY;
const int gForWrite = O_WRONLY;

class Fifo
{
private:
    void OpenFifo(int flag)
    {
        //打开管道, 传不同的标志位
        _fd = ::open(gpipeFile.c_str(), flag);
        if(_fd < 0)
        {
            std::cerr << "open error" << std::endl;
        }
    }
public:
    Fifo():_fd(-1)
    {
        //把umask缺省权限置为0
        umask(0);
        //创建命名管道
        int n = ::mkfifo(gpipeFile.c_str(), gfifomode);
        if(n < 0)
        {
            //std::cerr << "mkfifo error" << std::endl;
            return ;
        }
        std::cout << "mkfifo success" << std::endl;
    }
    //以只写的方式打开
    bool OpenPipeForWrite()
    {
        OpenFifo(gForWrite);
        if(_fd < 0)
            return false;
        return true;
    }
    //以只读的方式打开
    bool OpenPipeForRead()
    {
        OpenFifo(gFoeRead);
        if(_fd < 0)
            return false;
        return true;
    }
    //等待, 读阻塞等待写入完成
    int Wait()
    {
        int code = 0;
        //ssize_t 有符号整型 与long long 类似
        ssize_t n = ::read(_fd, &code, sizeof(code));
        if(n == sizeof(code))
            return 0;//读取成功
        else if(n == 0)
            return 1;
        else
        {
            return 2;
        }
    }
    //写入, 传递信号, 表示当前共享内存写入已经完毕
    void Signal()
    {
        int code = 1;
        ::write(_fd, &code, sizeof(code));
    }
    ~Fifo()
    {
        //关闭文件
        if(_fd >= 0)
            ::close(_fd);
        //解除关联, 删除管道
        int n = ::unlink(gpipeFile.c_str());
        if(n < 0)
        {
            std::cerr << "unlink error" << std::endl;
            return ;
        }
        std::cout << "unlink success" << std::endl;
    }
private:
    int _fd;//文件描述符

};

Fifo gpipe;